package model;

import java.util.ArrayList;
import java.util.List;

import Main.Mysql;

@SuppressWarnings("rawtypes")
public class Noeud implements java.lang.Comparable {
	private int id;
	private String balise;
	private int order;
	private int idPere = -1;
	private int idDocument = -1;
	private static Mysql bdd;
	
	private List<Noeud> fils;
	
	private static int nbTotalNoeuds = -1;
	

	private float somme_tfidf_carre = 0;
	private double eval = 0.0;
	private double somme_valTerme_carre = 0.0;
	private double somme_tfidf_valTerme = 0.0;


	public Noeud (int id, String balise, int order){
		this.id=id;
		this.balise=balise;
		this.order=order;
		bdd = Mysql.getInstance();
		fils = searchFils();
		if (nbTotalNoeuds == -1) {	
			String req = "SELECT COUNT(N.id) " +
				 "FROM Noeuds N " + ";";
			List<List> result = bdd.getResultSet (bdd.executeSelect(req));
			nbTotalNoeuds = Integer.parseInt((String) result.get(0).get(0));	
		}
		
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getBalise() {
		return balise;
	}

	public void setBalise(String balise) {
		this.balise = balise;
	}

	public int getOrder() {
		return order;
	}

	public void setOrder(int order) {
		this.order = order;
	}
	
	public int getIdPere() {
		return idPere;
	}

	public void setIdPere(int idPere) {
		this.idPere = idPere;
	}

	public int getIdDocument() {
		return idDocument;
	}

	public void setIdDocument(int idDocument) {
		this.idDocument = idDocument;
	}
	
	public ArrayList<Noeud> searchFils () {
		ArrayList<Noeud> lst = new ArrayList<Noeud>();
		String req = "SELECT N.id, N.nomBalise, N.ordre " +
				 "FROM NoeudNoeud NN, Noeuds N " +
				 "WHERE NN.idPere =" + this.id + " " +
				 "AND NN.idFils = N.id;";
		List<List> result = bdd.getResultSet (bdd.executeSelect(req));
		
		for (int i=0;i<result.size();i++) {
			Noeud n = new Noeud(Integer.parseInt((String) result.get(i).get(0)), (String)result.get(i).get(1), Integer.parseInt((String) result.get(i).get(2)));
			lst.add(n);
		}
		
		return lst;
	}

	public int getFrequenceTermeByIdNoeud (int idTerme) {
		String req = "SELECT TN.idTerme, TN.idNoeud, TN.frequence " +
				 "FROM TermeNoeud TN " +
				 "WHERE TN.idTerme =" + idTerme + " " +
				 "AND TN.idNoeud =" + this.id + ";";

		List<List> result = bdd.getResultSet (bdd.executeSelect(req));
		
		int dansCeNoeud =  Integer.parseInt((String) result.get(0).get(2));
		int dansLesFils = 0;
		for (int i=0;i<fils.size();i++) {
			dansLesFils += fils.get(i).getFrequenceTermeByIdNoeud(idTerme);
		}
		
		return dansCeNoeud + dansLesFils;
	}
	
	public int getNbTotalTermes () {
		String req = "SELECT TN.idNoeud, SUM(TN.frequence) " +
				 "FROM TermeNoeud TN " +
				 "WHERE TN.idNoeud =" + this.id + ";";
		List<List> result = bdd.getResultSet (bdd.executeSelect(req));
		int dansCeNoeud = Integer.parseInt((String) result.get(0).get(1));
		int dansLesFils = 0;
		for (int i=0;i<fils.size();i++) {
			dansLesFils += fils.get(i).getNbTotalTermes();
		}
		
		return dansCeNoeud + dansLesFils;
	}
	
	public int getNbNoeudsAvecTerme (int idTerme) {
		String req = "SELECT COUNT(TN.idNoeud) " +
				 "FROM TermeNoeud TN " +
				 "WHERE TN.idTerme =" + idTerme + ";";
		List<List> result = bdd.getResultSet (bdd.executeSelect(req));
		return Integer.parseInt((String) result.get(0).get(0));
	}
	
	
	public void setVariables (int idTerme, Double valTerme) {
		float tf = (float) getFrequenceTermeByIdNoeud (idTerme) / (float) getNbTotalTermes ();
		float idf = (float) Math.log( (float) nbTotalNoeuds/ (float) getNbNoeudsAvecTerme (idTerme));
		float tfidf = tf * idf;
		this.somme_tfidf_carre += tfidf*tfidf;
		this.somme_valTerme_carre += valTerme * valTerme;
		this.somme_tfidf_valTerme += tf * idf * valTerme;
	}

	public void setEval(double eval)
	{
		this.eval = eval;
	}
	
	public double getEval()
	{
		this.eval = somme_tfidf_valTerme/(Math.sqrt(somme_tfidf_carre+somme_valTerme_carre));
		return this.eval;
	}
	
	@Override
	public int compareTo(Object arg0) {
		double evalThis = this.eval;
		double evalOther = ((Noeud)arg0).eval;
		if (evalThis==evalOther) {
			return 0;
		} else if (evalThis < evalOther) {
			return -1;
		} else {
			return 1;
		}
	}
	
	public String getPath() {
		String req = "SELECT NN.idPere, N.nomBalise, N.ordre " +
				 "FROM NoeudNoeud NN, Noeuds N " +
				 "WHERE NN.idFils =" + this.id + " " +
				 "AND NN.idPere = N.id;";
		List<List> result = bdd.getResultSet (bdd.executeSelect(req));
		
		if (result.size() != 0) {
			int idDuPere = Integer.parseInt((String) result.get(0).get(0));
			String baliseDuPere = (String) result.get(0).get(1);
			int ordreDuPere = Integer.parseInt((String) result.get(0).get(2));
			Noeud pere = new Noeud (idDuPere, baliseDuPere, ordreDuPere);
			return pere.toString() + "/";
		} else {
			req = "SELECT D.nom " +
					 "FROM DocNoeud DN, Documents D " +
					 "WHERE DN.idNoeud =" + this.id + " " +
					 "AND DN.idDoc = D.id;";
			result.clear();
			result = bdd.getResultSet (bdd.executeSelect(req));
			
			return "Collection/"+ (String) result.get(0).get(0) + " /" ; // le nom du doc			
		}
		
	}
	
	public String toString () {
		return getPath() + balise + "[" + order + "]";
	}
}